namespace Vibstudio.NetConfigurator.IoC
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Reflection;

    public class PluginManager
    {
        private readonly Dictionary<PluginAttribute, PluginInfo> _loadedPlugins =
            new Dictionary<PluginAttribute, PluginInfo>();

        public PluginManager(String pluginDirectory)
        {
            ScanDirectory(pluginDirectory);
        }

        private void ScanDirectory(String directoryName)
        {
            foreach (String fileName in Directory.GetFiles(directoryName, "*.dll"))
            {
                AnalyzeAssemblyFile(fileName);
            }
        }

        private void AnalyzeAssemblyFile(String fileName)
        {
            try
            {
                Assembly asm = Assembly.LoadFrom(fileName);
                foreach (Type ty in asm.GetTypes())
                {
                    if (ty.IsDefined(typeof (PluginAttribute), false))
                    {
                        _loadedPlugins.Add(
                            (PluginAttribute) Attribute.GetCustomAttribute(ty, typeof (PluginAttribute)),
                            new PluginInfo(ty));
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(string.Format("Exception: {0}", ex.Message), "PluginManager.AnalyzeAssemblyFile");
            }
        }

        public List<PluginAttribute> GetPluginListForInterface(String intefaceName)
        {
            return (from plugin in _loadedPlugins
                    where plugin.Value.ImplementInterface(intefaceName)
                    select plugin.Key).ToList();
        }

        public T CreateInstance<T>(PluginAttribute info)
        {
            return (T) Activator.CreateInstance(_loadedPlugins[info].PluginType);
        }
    }
}